load_seg(0, base, limit, arbytes);
}
+static unsigned char rm_irqbase[2];
/*
* Transition to protected mode
{
extern char stack_top[];
+ oldctx.rm_irqbase[0] = rm_irqbase[0];
+ oldctx.rm_irqbase[1] = rm_irqbase[1];
+
regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM);
oldctx.eip = regs->eip;
icw2[0] = 0;
printf("Remapping master: ICW2 0x%x -> 0x%x\n",
al, NR_EXCEPTION_HANDLER);
+ rm_irqbase[0] = al;
al = NR_EXCEPTION_HANDLER;
}
break;
icw2[1] = 0;
printf("Remapping slave: ICW2 0x%x -> 0x%x\n",
al, NR_EXCEPTION_HANDLER+8);
+ rm_irqbase[1] = al;
al = NR_EXCEPTION_HANDLER+8;
}
break;
static int vmx_assist(struct vcpu *v, int mode)
{
struct vmx_assist_context c;
- u32 magic;
- u32 cp;
+ struct hvm_hw_vpic *vpic = v->domain->arch.hvm_domain.vpic;
+ u32 magic, cp;
/* make sure vmxassist exists (this is not an error) */
if (hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
goto error;
if ( vmx_world_restore(v, &c) != 0 )
goto error;
+ v->arch.hvm_vmx.pm_irqbase[0] = vpic[0].irq_base;
+ v->arch.hvm_vmx.pm_irqbase[1] = vpic[1].irq_base;
+ vpic[0].irq_base = NR_EXCEPTION_HANDLER;
+ vpic[1].irq_base = NR_EXCEPTION_HANDLER + 8;
v->arch.hvm_vmx.vmxassist_enabled = 1;
- /*
- * The 32-bit vmxassist vm86.c support code is hard-coded to
- * expect vPIC interrupts to arrive at interrupt traps 0x20-0x27
- * and 0x28-0x2f. It bounces these to 16-bit boot code traps
- * 0x08-0x0f and 0x70-0x77. But when the guest transitions
- * to true native 32-bit mode, vmxassist steps out of the
- * way and no such bouncing occurs; so we need to rewrite
- * the vPIC irq base to point directly to 0x08/0x70 (see
- * code just below). So on re-entering 16-bit mode, we need
- * to reset the vPICs to go back to the 0x20/0x28 bounce traps.
- */
- v->domain->arch.hvm_domain.vpic[0].irq_base = 0x20;
- v->domain->arch.hvm_domain.vpic[1].irq_base = 0x28;
return 1;
}
break;
goto error;
if ( vmx_world_restore(v, &c) != 0 )
goto error;
+ if ( v->arch.hvm_vmx.irqbase_mode ) {
+ vpic[0].irq_base = c.rm_irqbase[0] & 0xf8;
+ vpic[1].irq_base = c.rm_irqbase[1] & 0xf8;
+ } else {
+ vpic[0].irq_base = v->arch.hvm_vmx.pm_irqbase[0];
+ vpic[1].irq_base = v->arch.hvm_vmx.pm_irqbase[1];
+ }
v->arch.hvm_vmx.vmxassist_enabled = 0;
- /*
- * See comment above about vmxassist 16/32-bit vPIC behaviour.
- * The irq_base values are hard-coded into vmxassist vm86.c.
- */
- v->domain->arch.hvm_domain.vpic[0].irq_base = 0x08;
- v->domain->arch.hvm_domain.vpic[1].irq_base = 0x70;
return 1;
}
break;
return irq;
}
-static void vpic_ioport_write(struct hvm_hw_vpic *vpic, uint32_t addr, uint32_t val)
+static void vpic_ioport_write(
+ struct hvm_hw_vpic *vpic, uint32_t addr, uint32_t val)
{
int priority, cmd, irq;
uint8_t mask;
vpic->imr = val;
break;
case 1:
+#if 1 /* Delete me when vmxassist is retired. */
+ /* Which mode is irqbase programmed in? */
+ current->arch.hvm_vmx.irqbase_mode =
+ current->arch.hvm_vmx.vmxassist_enabled;
+#endif
/* ICW2 */
vpic->irq_base = val & 0xf8;
vpic->init_state++;
#ifndef __ASSEMBLY__
+#define NR_EXCEPTION_HANDLER 32
+#define NR_INTERRUPT_HANDLERS 16
+#define NR_TRAPS (NR_EXCEPTION_HANDLER+NR_INTERRUPT_HANDLERS)
+
union vmcs_arbytes {
struct arbyte_fields {
unsigned int seg_type : 4,
uint32_t ldtr_limit;
uint32_t ldtr_base;
union vmcs_arbytes ldtr_arbytes;
+
+ unsigned char rm_irqbase[2];
};
typedef struct vmx_assist_context vmx_assist_context_t;